package com.xcm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.xcm.config.CustomProperties;
import com.xcm.constant.*;
import com.xcm.dao.ProgramJsonMapper;
import com.xcm.exception.ServiceException;
import com.xcm.export.entity.SingleProgramDetailReportData;
import com.xcm.model.*;
import com.xcm.model.dto.AuthProgramJsonDTO;
import com.xcm.model.dto.ProgramJsonListDTO;
import com.xcm.model.dto.SingleProgramDetailReportDTO;
import com.xcm.model.dto.WholeProgramReportDTO;
import com.xcm.model.vo.ProgramJsonStatVO;
import com.xcm.model.vo.SingleProgramDetailReportVO;
import com.xcm.model.vo.WholeProgramReportVO;
import com.xcm.page.PageInfo;
import com.xcm.service.*;
import com.xcm.util.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.List;

/**
 * 节目JsonService实现类
 */
@Service(value = "programJsonService")
public class ProgramJsonServiceImpl implements ProgramJsonService {
	private static Logger logger = LoggerFactory.getLogger(ProgramJsonServiceImpl.class);
	@Autowired
	private ProgramJsonMapper programJsonMapper;
	@Autowired
	private ProgramTopService programTopService;
	@Autowired
	private ProgramBottomService programBottomService;
	@Autowired
	private ProgramInfoService programInfoService;
	@Autowired
	private OperationLogService operationLogService;
	@Autowired
	private CustomProperties customProperties;

	/**
	 * 发布节目
	 * publishProgram
	 *
	 * @param xcVersion xc版本号
	 * @param url     Json文件下载地址
	 * @param request HttpServletRequest
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public String publishProgram(String xcVersion, String url, HttpServletRequest request) throws UnsupportedEncodingException, ServiceException {
		String jsonFileSavePath = customProperties.getJsonFileSavePath();
		//验证json文件保存路径是否为空
		if (StringUtils.isBlank(jsonFileSavePath)) {
			return "json文件保存路径为空";
		}
		//对Url进行解码
		url = DecodeUtils.decodeUnicode(url);
		//根据xc版本查询TbProgramJson
		TbProgramJson programJson = programJsonMapper.getProgramJsonByXcVersion(xcVersion);
		//数据已存在
		if (programJson != null) {
			return xcVersion + "版本的数据已存在";
		}
		//获取Ip地址
		String remortIP = HttpUtils.getRemortIP(request);
		//保存节目Json
		programJson = new TbProgramJson();
		programJson.setXcVersion(xcVersion);
		programJson.setCmsVersion(String.valueOf(System.currentTimeMillis()));
		programJson.setReceiveTime(System.currentTimeMillis());
		programJson.setUrl(url);
		programJson.setPublishWay(BusinessConstant.PROGRAM_JSON_PUBLISH_WAY_TIMING);
		int lastindex = url.lastIndexOf("/");
		String name = url.substring(lastindex + 1);
		programJson.setName(name);
		programJson.setDownState(BusinessConstant.PROGRAMJSON_STATE_DOWNLOADING);
		programJson.setJsonAuth(BusinessConstant.PROGRAMJSON_AUTH_STATE_NO_VALIDATE);
		//保存节目JSON信息
		saveProgramJson(programJson);
		//保存成功后，再查询一次，需要更新节目JSON相关信息
		TbProgramJson newProgramJson = programJsonMapper.getProgramJsonByXcVersion(xcVersion);
		if (newProgramJson == null){
			logger.error("ProgramJsonServiceImpl publishProgram 保存节目JSON失败");
			return "保存节目JSON";
		}
		programJson = newProgramJson;
		//系统分隔符
		String separator = File.separator;
		//json文件存放目录
		File destDir = new File(jsonFileSavePath);
		if (!destDir.exists()) {
			destDir.mkdirs();
		}
		//json文件存放路径
		String dest = "";
		if (jsonFileSavePath.endsWith(separator)) {
			dest = jsonFileSavePath + name;
		} else {
			dest = jsonFileSavePath + separator + name;
		}
		try {
			//下载文件
			FileUtils.downloadFileFromURL(url,dest);
		} catch (IOException e) {
			//更新下载状态
			Integer downState = BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_FAIL;
			programJsonMapper.updateProgramJsonDownStateById(downState, programJson.getProgramJsonId());
			//保存操作日志
			TbOperationLog operationLog = new TbOperationLog();
			operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
			operationLog.setOperationContent(programJson.getName() + "发布失败,下载文件失败");
			operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
			operationLog.setOperationTime(System.currentTimeMillis());
			//DSP调用IPS接口，没有用户信息
			operationLog.setUserName("");
			operationLog.setRealName("");
			operationLog.setOperationIp(remortIP);
			operationLogService.saveOperationLog(operationLog);
			logger.error("ProgramJsonServiceImpl publishProgram 下载文件失败" + e.getMessage());
			e.printStackTrace();
			throw new ServiceException("下载文件失败");
		}
		//读取文件
		String data = FileUtils.readFile(dest);
		if (StringUtils.isBlank(data)) {
			//下载失败
			Integer downState = BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_FAIL;
			programJsonMapper.updateProgramJsonDownStateById(downState, programJson.getProgramJsonId());
			//保存操作日志
			TbOperationLog operationLog = new TbOperationLog();
			operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
			operationLog.setOperationContent(programJson.getName() + "发布失败,文件内容为空");
			operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
			operationLog.setOperationTime(System.currentTimeMillis());
			//DSP调用IPS接口，没有用户信息
			operationLog.setUserName("");
			operationLog.setRealName("");
			operationLog.setOperationIp(remortIP);
			operationLogService.saveOperationLog(operationLog);
			logger.error("ProgramJsonServiceImpl publishProgram 文件内容为空");
			return "文件内容为空";
		}
		programJson.setDeviceDownState(BusinessConstant.PROGRAMJSON_DEVICE_DOWNLOADING);
		programJson.setDownState(BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_SUCESS);
		programJson.setPath(url);
		programJsonMapper.updateProgramJson(programJson);

		JSONObject jsonObject = null;
		try {
			jsonObject = JSON.parseObject(data);
		} catch (Exception e) {
			//保存操作日志
			TbOperationLog operationLog = new TbOperationLog();
			operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
			operationLog.setOperationContent(programJson.getName() + "发布失败,JSON格式错误，无法解析文件内容");
			operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
			operationLog.setOperationTime(System.currentTimeMillis());
			//DSP调用IPS接口，没有用户信息
			operationLog.setUserName("");
			operationLog.setRealName("");
			operationLog.setOperationIp(remortIP);
			operationLogService.saveOperationLog(operationLog);
			logger.error("ProgramJsonServiceImpl publishProgram JSON格式错误，无法解析文件内容");
			return "JSON格式错误，无法解析文件内容";
		}

		//上屏节目
		JSONArray topOrders = jsonObject.getJSONArray(BusinessConstant.JSON_KEY_TOPORDERS);
		if (topOrders != null && topOrders.size() > 0) {
			List<TbProgramTop> topList = Lists.newArrayList();
			for (int i = 0; i < topOrders.size(); i++) {
				JSONObject top = topOrders.getJSONObject(i);
				TbProgramTop programTop = new TbProgramTop();
				programTop.setXcVersion(programJson.getXcVersion());
				programTop.setCmsVersion(programJson.getCmsVersion());
				programTop.setName(top.getString(BusinessConstant.JSON_KEY_NAME));
				programTop.setUrl(top.getString(BusinessConstant.JSON_KEY_URL));
				programTop.setMd5(top.getString(BusinessConstant.JSON_KEY_MD5));
				programTop.setType(FileConstant.FILE_TYPE_VIDEO);
				programTop.setAddTime(System.currentTimeMillis());
				//毫秒
				Integer length = top.getInteger(BusinessConstant.JSON_KEY_LENGTH);
				if (length != null) {
					// TODO: 2018/5/25 DSP传过来的值是精确到秒的，自己组装的数据是毫秒值
					//大于1000，是毫秒值了，就不乘以10000
					if (length > 1000) {
						programTop.setDuration(length);
					} else {
						programTop.setDuration(length * 1000);
					}
				}
				topList.add(programTop);
			}
			programTopService.saveProgramTopBatch(topList);
		}

		//下屏节目
		JSONArray bottomOrders = jsonObject.getJSONArray(BusinessConstant.JSON_KEY_BOTTOMORDERS);
		if (bottomOrders != null && bottomOrders.size() > 0) {
			List<TbProgramBottom> bottomList = Lists.newArrayList();
			for (int i = 0; i < bottomOrders.size(); i++) {
				JSONObject bottom = bottomOrders.getJSONObject(i);
				TbProgramBottom programBottom = new TbProgramBottom();
				programBottom.setXcVersion(programJson.getXcVersion());
				programBottom.setCmsVersion(programJson.getCmsVersion());
				programBottom.setName(bottom.getString(BusinessConstant.JSON_KEY_NAME));
				programBottom.setUrl(bottom.getString(BusinessConstant.JSON_KEY_URL));
				programBottom.setType(FileConstant.FILE_TYPE_PICTURE);
				//毫秒
				Integer length = bottom.getInteger(BusinessConstant.JSON_KEY_LENGTH);
				if (length != null) {
					//DSP传过来的值是精确到秒的，自己组装的数据是毫秒值
					//大于1000，是毫秒值了，就不乘以10000
					if (length > 1000) {
						programBottom.setDuration(length);
					} else {
						programBottom.setDuration(length * 1000);
					}
				}
				programBottom.setMd5(bottom.getString(BusinessConstant.JSON_KEY_MD5));
				programBottom.setAddTime(System.currentTimeMillis());
				bottomList.add(programBottom);
			}
			programBottomService.saveProgramBottomBatch(bottomList);
		}
		//节目信息
		JSONArray orders = jsonObject.getJSONArray(BusinessConstant.JSON_KEY_ORDERS);
		if (orders != null) {
			//设置终端数，终端下载成功后才开始计数
			programJson.setDeviceNum(0);
			//programJsonMapper.updateProgramJson(programJson);
			List<TbProgramInfo> programInfoList = Lists.newArrayList();
			for (int i = 0; i < orders.size(); i++) {
				Object obj = orders.get(i);
				if (obj == null) {
					continue;
				}
				JSONObject orderObj = (JSONObject) obj;
				String top = orderObj.getJSONArray(BusinessConstant.JSON_KEY_TOP).toJSONString().replace("[", "").replace("]", "");
				String bottom = orderObj.getJSONArray(BusinessConstant.JSON_KEY_BOTTOM).toJSONString().replace("[", "").replace("]", "");
				TbProgramInfo programInfo = new TbProgramInfo();
				programInfo.setXcVersion(programJson.getXcVersion());
				programInfo.setCmsVersion(programJson.getCmsVersion());
				programInfo.setMachineNum(orderObj.getString(BusinessConstant.JSON_KEY_MACHINE_NUM));
				programInfo.setTop(top);
				programInfo.setBottom(bottom);
				programInfo.setAddTime(System.currentTimeMillis());
				programInfoList.add(programInfo);
			}
			programInfoService.saveProgramTopBatch(programInfoList);
		}
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
		operationLog.setOperationContent(programJson.getName() + "发布成功");
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		//DSP调用IPS接口，没有用户信息
		operationLog.setUserName("");
		operationLog.setRealName("");
		operationLog.setOperationIp(remortIP);
		operationLogService.saveOperationLog(operationLog);
		//成功返回空字符串
		return "";
	}

	/**
	 * 保存节目Json
	 * saveProgramJson
	 *
	 * @param programJson TbProgramJson类型对象
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void saveProgramJson(TbProgramJson programJson) {
		programJsonMapper.saveProgramJson(programJson);
	}

	/**
	 * 获取节目Json列表(分页)
	 * listProgramJsonByPage
	 *
	 * @param timeType        筛选时间类型称
	 * @param startTime       筛选时间-开始
	 * @param endTime         筛选时间-结束
	 * @param deviceDownState 终端下载状态
	 * @param checkType       校验状态
	 * @param publishId       发布Id
	 * @param pageNum         当前页
	 * @param pageSize        每页显示条数
	 * @return Page<ProgramJsonListDTO>
	 */
	@Override
	public Page<ProgramJsonListDTO> listProgramJsonByPage(String timeType, String startTime, String endTime, String deviceDownState, String checkType, Long publishId, Integer pageNum, Integer pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		Long start = null;
		Long end = null;
		try {
			if (StringUtils.isNotBlank(startTime)) {
				start = DateUtils.stringTimeToLongTimeStamp(startTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
			if (StringUtils.isNotBlank(endTime)) {
				end = DateUtils.stringTimeToLongTimeStamp(endTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return programJsonMapper.listProgramJsonByPage(timeType, start, end, deviceDownState, checkType, publishId);
	}

	/**
	 * 通过xc版本获取节目Json
	 * getProgramJsonByXcVersion
	 *
	 * @param xcVersion xc版本号
	 * @return TbProgramJson
	 */
	@Override
	public TbProgramJson getProgramJsonByXcVersion(String xcVersion) {
		return programJsonMapper.getProgramJsonByXcVersion(xcVersion);
	}

	/**
	 * 获取终端下载广告成功数量（所有终端下载完毕该批次广告，成功数量+1,多一个终端对应一批广告，有一个失败即失败数+1）
	 *
	 * @return Long
	 */
	@Override
	public Long getProgramJsonConutByDeviceDownState(Integer state) {
		return programJsonMapper.getProgramJsonConutByDeviceDownState(state);
	}

	/**
	 * 根据下载云端推送广告状态获取广告数量
	 *
	 * @return Long
	 */
	@Override
	public Long getProgramJsonCountByDownloadState(Integer state) {
		return programJsonMapper.getProgramJsonCountByDownloadState(state);
	}

	/**
	 * 获取单个节目详细报表列分页表
	 *
	 * @param receiveStartTime 接收开始时间
	 * @param receiveEndTime   接收结束时间
	 * @param programJsonId    节目主键ID
	 * @param pageNum          当前页
	 * @param pageSize         每页多少条
	 * @return PageInfo<SingleProgramDetailReportVO>
	 */
	@Override
	public PageInfo<SingleProgramDetailReportVO> listSingleProgramDetailReportByPage(String receiveStartTime, String receiveEndTime, Long programJsonId, Integer pageNum, Integer pageSize) {
		if (pageNum == null) {
			pageNum = PageConstant.DEFAULT_PAGE_NUM;
		}
		if (pageSize == null) {
			pageSize = PageConstant.DEFAULT_PAGE_SIZE;
		}
		Long longReceiveStartTime = null;
		Long longReceiveEndTime = null;
		try {
			if (StringUtils.isNotBlank(receiveStartTime)) {
				longReceiveStartTime = DateUtils.stringTimeToLongTimeStamp(receiveStartTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
			if (StringUtils.isNotBlank(receiveEndTime)) {
				longReceiveEndTime = DateUtils.stringTimeToLongTimeStamp(receiveEndTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		PageHelper.startPage(pageNum, pageSize);
		Page<SingleProgramDetailReportDTO> page = programJsonMapper.listSingleProgramDetailReportByPage(longReceiveStartTime, longReceiveEndTime, programJsonId);
		if (page == null) {
			return new PageInfo<SingleProgramDetailReportVO>(pageNum, pageSize, 0L, null);
		}
		PageInfo pageInfo = new PageInfo<SingleProgramDetailReportVO>();
		pageInfo.setPageNum(pageNum);
		pageInfo.setPageSize(pageSize);
		pageInfo.setTotal(page.getTotal());
		//把long类型时间转化为格式化时间
		List<SingleProgramDetailReportDTO> dtoList = page.getResult();
		List<SingleProgramDetailReportVO> voList = Lists.newArrayList();
		for (SingleProgramDetailReportDTO dto : dtoList) {
			SingleProgramDetailReportVO vo = new SingleProgramDetailReportVO();
			vo.setProgramJsonId(dto.getProgramJsonId());
			vo.setPublishWay(dto.getPublishWay() == null ? "" : "定期发布");
			vo.setReceiveTime(dto.getRecieveTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getRecieveTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			vo.setDoneTime(dto.getDoneTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getDoneTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			vo.setMachineNum(dto.getMachineNum());
			vo.setMac(dto.getMac());
			vo.setDeviceProvince(dto.getDeviceProvince());
			vo.setDeviceCity(dto.getDeviceCity());
			vo.setDeviceCounty(dto.getDeviceCounty());
			Integer downloadState = dto.getDownloadState();
			if (downloadState == null) {
				vo.setDownloadState("");
			} else {
				if (BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_FAIL == downloadState) {
					vo.setDownloadState("下载失败");
				}
				if (BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_SUCESS == downloadState) {
					vo.setDownloadState("已下载");
				}
				if (BusinessConstant.PROGRAMJSON_STATE_DOWNLOADING == downloadState) {
					vo.setDownloadState("下载中");
				}
			}
			vo.setGroupName(dto.getGroupName());
			voList.add(vo);
		}
		pageInfo.setList(voList);
		return pageInfo;
	}

	/**
	 * 获取导出单个节目详细报表列表
	 *
	 * @param receiveStartTime 接收开始时间
	 * @param receiveEndTime   接收结束时间
	 * @param programJsonId    节目主键ID
	 * @return List<SingleProgramDetailReportData>
	 */
	@Override
	public List<SingleProgramDetailReportData> listExportSingleProgramDetailReport(String receiveStartTime, String receiveEndTime, Long programJsonId) {
		Long exportReceiveStartTime = null;
		Long exportReceiveEndTime = null;
		try {
			if (StringUtils.isNotBlank(receiveStartTime)) {
				exportReceiveStartTime = DateUtils.stringTimeToLongTimeStamp(receiveStartTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
			if (StringUtils.isNotBlank(receiveEndTime)) {
				exportReceiveEndTime = DateUtils.stringTimeToLongTimeStamp(receiveEndTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		//导出列表
		List<SingleProgramDetailReportData> exportDataList = Lists.newArrayList();
		Page<SingleProgramDetailReportDTO> page = programJsonMapper.listSingleProgramDetailReportByPage(exportReceiveStartTime, exportReceiveEndTime, programJsonId);
		if (page == null) {
			return exportDataList;
		}
		//DTO列表
		List<SingleProgramDetailReportDTO> exportDtoList = page.getResult();
		if (CollectionUtils.isEmpty(exportDtoList)) {
			return exportDataList;
		}
		for (SingleProgramDetailReportDTO dto : exportDtoList) {
			SingleProgramDetailReportData data = new SingleProgramDetailReportData();
			data.setProgramJsonId(dto.getProgramJsonId());
			data.setPublishWay(dto.getPublishWay() == null ? "" : "定期发布");
			data.setRecieveTime(dto.getRecieveTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getRecieveTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			data.setDoneTime(dto.getDoneTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getDoneTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			data.setMachineNum(dto.getMachineNum());
			data.setMac(dto.getMac());
			data.setDeviceProvince(dto.getDeviceProvince());
			data.setDeviceCity(dto.getDeviceCity());
			data.setDeviceCounty(dto.getDeviceCounty());
			Integer downloadState = dto.getDownloadState();
			if (BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_FAIL == downloadState) {
				data.setDownloadState("下载失败");
			}
			if (BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_SUCESS == downloadState) {
				data.setDownloadState("已下载");
			}
			if (BusinessConstant.PROGRAMJSON_STATE_DOWNLOADING == downloadState) {
				data.setDownloadState("下载中");
			}
			data.setGroupName(dto.getGroupName());
			exportDataList.add(data);
		}
		return exportDataList;
	}

	/**
	 * 获取广告校验失败数
	 *
	 * @return Long
	 */
	@Override
	public Long getProgramJsonAuthFailureCount() {
		return programJsonMapper.getProgramJsonConutByJsonAuth(BusinessConstant.PROGRAMJSON_AUTH_STATE_FAIL);
	}

	/**
	 * 获取广告发布失败数量
	 *
	 * @return Long
	 */
	@Override
	public Long getProgramJsonPublishFailureCount() {
		return programJsonMapper.getProgramJsonConutByDeviceDownState(BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_FAIL);
	}

	/**
	 * 获取广告总数
	 *
	 * @return Long
	 */
	@Override
	public Long getProgramJsonCount() {
		return programJsonMapper.getProgramJsonCount();
	}

	/**
	 * 获取整体广告分页列表
	 * @param timeType 1:接收时间 2:完成时间
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @param publishWay 发布方式 1：定时发布(当前只有定时发布) 2:预约发布
	 * @param programJsonId 发布Id
	 * @param pageNum 当前页数
	 * @param pageSize 每页条数
	 * @return
	 */
	@Override
	public PageInfo<WholeProgramReportVO> listWholeProgramReportByPage(Integer timeType, String startTime, String endTime, Integer publishWay, Long programJsonId, Integer pageNum, Integer pageSize) {
		pageNum = pageNum == null ? PageConstant.DEFAULT_PAGE_NUM : pageNum;
		pageSize = pageSize == null ? PageConstant.DEFAULT_PAGE_SIZE : pageSize;
		Long longStartTime = null;
		Long longEndTime = null;
		try {
			if(StringUtils.isNotBlank(startTime)) {
				longStartTime = DateUtils.stringTimeToLongTimeStamp(startTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
            }
			if(StringUtils.isNotBlank(endTime)) {
				longEndTime = DateUtils.stringTimeToLongTimeStamp(endTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
            }
		} catch (ParseException e) {
			e.printStackTrace();
		}
		PageHelper.startPage(pageNum, pageSize);
		Page<WholeProgramReportDTO> page = programJsonMapper.listWholeProgramReportByPage(timeType, longStartTime, longEndTime, publishWay, programJsonId);

		if (page == null) {
			return new PageInfo<>(pageNum, pageSize, 0L, null);
		}

		PageInfo pageInfo = new PageInfo<WholeProgramReportVO>();
		pageInfo.setPageNum(pageNum);
		pageInfo.setPageSize(pageSize);
		pageInfo.setTotal(page.getTotal());
		//把long类型时间转化为格式化时间
		List<WholeProgramReportDTO> dtoList = page.getResult();
		List<WholeProgramReportVO> voList = Lists.newArrayList();
		for (WholeProgramReportDTO dto : dtoList) {
			WholeProgramReportVO vo = new WholeProgramReportVO();
			vo.setProgramJsonId(dto.getProgramJsonId().toString());
			vo.setPublishWay(dto.getPublishWay() == null ? "" : "定期发布");
			vo.setReceiveTime(dto.getReceiveTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getReceiveTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			vo.setDoneTime(dto.getDoneTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getDoneTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			vo.setDeviceNum(dto.getDeviceNum().toString());
			vo.setDeviceSuccessNum(dto.getDeviceSuccessNum().toString());
			vo.setDeviceFailNum(dto.getDeviceFailNum().toString());
			voList.add(vo);
		}
		pageInfo.setList(voList);
		return pageInfo;
	}

	/**
	 * 获取节目相关统计信息
	 */
	@Override
	public ProgramJsonStatVO getProgramJsonStat() {
		return programJsonMapper.getProgramJsonStat();
	}

	/**
	 *  TODO 导入JSON发布广告
	 *  @param version 版本
	 * @param file json文件
     * @param user
     * @param request
     */
	@Override
	public void publishProgramByJsonFile(String version, MultipartFile file, JSONObject user, HttpServletRequest request) throws IOException {
		//更加xc版本查询TbProgramJson
		TbProgramJson programJson = programJsonMapper.getProgramJsonByXcVersion(version);
		//数据已存在
		if (programJson != null) {
			return;
		}
		//json文件存放目录
		String jsonFilePath = "xcips/json/";
		//文件下载路径
		String fileDownloadPath = HuaWeiCloudUtils.uploadFile2HuaweiCloud(file, jsonFilePath);
		String fileName = file.getOriginalFilename();
		//保存节目Json
		programJson = new TbProgramJson();
		programJson.setXcVersion(version);
		programJson.setCmsVersion(String.valueOf(System.currentTimeMillis()));
		programJson.setReceiveTime(System.currentTimeMillis());
		programJson.setUrl(fileDownloadPath);
		programJson.setName(fileName);
		programJson.setDownState(BusinessConstant.PROGRAMJSON_STATE_DOWNLOADING);
		programJson.setJsonAuth(BusinessConstant.PROGRAMJSON_AUTH_STATE_NO_VALIDATE);
		programJson.setPublishWay(BusinessConstant.PROGRAM_JSON_PUBLISH_WAY_TIMING);
		//保存节目JSON信息
		saveProgramJson(programJson);
		//保存成功后，再查询一次，需要更新节目JSON相关信息
		TbProgramJson newProgramJson = programJsonMapper.getProgramJsonByXcVersion(version);
		if (newProgramJson == null){
			logger.error("ProgramJsonServiceImpl publishProgramByJsonFile 导入节目JSON失败");
			return;
		}
		programJson = newProgramJson;

		//json文件存放目录
		String data = FileUtils.readFile(file);
		if (StringUtils.isBlank(data)) {
			Integer downState = BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_FAIL;
			//保存操作日志
			TbOperationLog operationLog = new TbOperationLog();
			operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
			operationLog.setOperationContent(programJson.getName() + "上传JSON文件失败,数据导入失败");
			operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
			operationLog.setOperationTime(System.currentTimeMillis());
			//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
			operationLog.setUserName(user.getString("userName"));
			operationLog.setRealName(user.getString("realName"));
			operationLog.setOperationIp(HttpUtils.getRemortIP(request));
			operationLogService.saveOperationLog(operationLog);
			programJsonMapper.updateProgramJsonDownStateById(downState, programJson.getProgramJsonId());
			return;
		}
		programJson.setDeviceDownState(BusinessConstant.PROGRAMJSON_DEVICE_DOWNLOADING);
		programJson.setDownState(BusinessConstant.PROGRAMJSON_STATE_DOWNLOAD_SUCESS);
		programJson.setPath(fileDownloadPath);
		programJsonMapper.updateProgramJson(programJson);

		long start = System.currentTimeMillis();
		JSONObject jsonObject = null;
		try {
			jsonObject = JSON.parseObject(data);
		} catch (Exception e) {
			//保存操作日志
			TbOperationLog operationLog = new TbOperationLog();
			operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
			operationLog.setOperationContent(programJson.getName() + "发布失败,JSON格式错误，无法解析文件内容");
			operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
			operationLog.setOperationTime(System.currentTimeMillis());
			//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
			operationLog.setUserName(user.getString("userName"));
			operationLog.setRealName(user.getString("realName"));
			operationLog.setOperationIp(HttpUtils.getRemortIP(request));
			operationLogService.saveOperationLog(operationLog);
			return;
		}
		if(null == jsonObject){
			return;
		}
		//上屏节目
		JSONArray topOrders = jsonObject.getJSONArray("topOrders");
		if (topOrders != null && topOrders.size() > 0) {
			List<TbProgramTop> topList = Lists.newArrayList();
			for (int i = 0; i < topOrders.size(); i++) {
				JSONObject top = topOrders.getJSONObject(i);
				TbProgramTop programTop = new TbProgramTop();
				programTop.setXcVersion(programJson.getXcVersion());
				programTop.setCmsVersion(programJson.getCmsVersion());
				programTop.setName(top.getString(BusinessConstant.JSON_KEY_NAME));
				programTop.setUrl(top.getString(BusinessConstant.JSON_KEY_URL));
				programTop.setMd5(top.getString(BusinessConstant.JSON_KEY_MD5));
				programTop.setType(FileConstant.FILE_TYPE_VIDEO);
				programTop.setAddTime(System.currentTimeMillis());
				//毫秒
				Integer length = top.getInteger(BusinessConstant.JSON_KEY_LENGTH);
				if (length != null) {
					// TODO: 2018/5/25 DSP传过来的值是精确到秒的，自己组装的数据是毫秒值
					//大于1000，是毫秒值了，就不乘以10000
					if (length > 1000) {
						programTop.setDuration(length);
					} else {
						programTop.setDuration(length * 1000);
					}
				}
				topList.add(programTop);
			}
			programTopService.saveProgramTopBatch(topList);
		}

		//下屏节目
		JSONArray bottomOrders = jsonObject.getJSONArray("bottomOrders");
		if (bottomOrders != null && bottomOrders.size() > 0) {
			List<TbProgramBottom> bottomList = Lists.newArrayList();
			for (int i = 0; i < bottomOrders.size(); i++) {
				JSONObject bottom = bottomOrders.getJSONObject(i);
				TbProgramBottom programBottom = new TbProgramBottom();
				programBottom.setXcVersion(programJson.getXcVersion());
				programBottom.setCmsVersion(programJson.getCmsVersion());
				programBottom.setName(bottom.getString(BusinessConstant.JSON_KEY_NAME));
				programBottom.setUrl(bottom.getString(BusinessConstant.JSON_KEY_URL));
				programBottom.setType(FileConstant.FILE_TYPE_PICTURE);
				//毫秒
				Integer length = bottom.getInteger(BusinessConstant.JSON_KEY_LENGTH);
				if (length != null) {
					//DSP传过来的值是精确到秒的，自己组装的数据是毫秒值
					//大于1000，是毫秒值了，就不乘以10000
					if (length > 1000) {
						programBottom.setDuration(length);
					} else {
						programBottom.setDuration(length * 1000);
					}
				}
				programBottom.setMd5(bottom.getString(BusinessConstant.JSON_KEY_MD5));
				programBottom.setAddTime(System.currentTimeMillis());
				bottomList.add(programBottom);
			}
			programBottomService.saveProgramBottomBatch(bottomList);
		}
		//节目信息
		JSONArray orders = jsonObject.getJSONArray("orders");
		if (orders != null) {
			//设置终端数，终端下载成功后才开始计数
			List<TbProgramInfo> programInfoList = Lists.newArrayList();
			for (int i = 0; i < orders.size(); i++) {
				Object obj = orders.get(i);
				if (obj == null) {
					continue;
				}
				JSONObject orderObj = (JSONObject) obj;
				String top = orderObj.getJSONArray(BusinessConstant.JSON_KEY_TOP).toJSONString().replace("[", "").replace("]", "");
				String bottom = orderObj.getJSONArray(BusinessConstant.JSON_KEY_BOTTOM).toJSONString().replace("[", "").replace("]", "");
				TbProgramInfo programInfo = new TbProgramInfo();
				programInfo.setXcVersion(programJson.getXcVersion());
				programInfo.setCmsVersion(programJson.getCmsVersion());
				programInfo.setMachineNum(orderObj.getString(BusinessConstant.JSON_KEY_MACHINE_NUM));
				programInfo.setTop(top);
				programInfo.setBottom(bottom);
				programInfo.setAddTime(System.currentTimeMillis());
				programInfoList.add(programInfo);
			}
			programInfoService.saveProgramTopBatch(programInfoList);
		}
		long end = System.currentTimeMillis();
		logger.info("解析JSON文件[" + fileName + "]耗时：" + (end - start) + "ms");
		//保存操作日志
		TbOperationLog operationLog = new TbOperationLog();
		operationLog.setOperationTypeId(OperationLogConstant.OPERATION_LOG_TYPE_PUBLISH);
		operationLog.setOperationContent(programJson.getName() + "发布成功");
		operationLog.setIsSuccess(OperationLogConstant.OPERATION_LOG_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		//展示设置操作用户名、用户真实姓名、IP为空，用户保存在统一登录系统
		operationLog.setUserName(user.getString("userName"));
		operationLog.setRealName(user.getString("realName"));
		operationLog.setOperationIp(HttpUtils.getRemortIP(request));
		operationLogService.saveOperationLog(operationLog);
	}

	/**
	 * 获取整体广告列表
	 * @param timeType      1:接收时间 2:完成时间
	 * @param startTime     开始时间
	 * @param endTime       结束时间
	 * @param publishWay    发布方式 1：定时发布(当前只有定时发布) 2:预约发布
	 * @param programJsonId 发布Id
	 * @return
	 */
	@Override
	public List<WholeProgramReportVO> listWholeProgramReport(Integer timeType, String startTime, String endTime, Integer publishWay, Long programJsonId) {
		List<WholeProgramReportVO> exportWholeProgramList = Lists.newArrayList();
		Long longStartTime = null;
		Long longEndTime = null;
		try {
			if(StringUtils.isNotBlank(startTime)) {
				longStartTime = DateUtils.stringTimeToLongTimeStamp(startTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
			if(StringUtils.isNotBlank(endTime)) {
				longEndTime = DateUtils.stringTimeToLongTimeStamp(endTime, DateFormatConstant.LONG_DATE_FORMAT_STR);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}

		Page<WholeProgramReportDTO> page = programJsonMapper.listWholeProgramReportByPage(timeType, longStartTime, longEndTime, publishWay, programJsonId);
		if (page == null) {
			return exportWholeProgramList;
		}
		List<WholeProgramReportDTO> wholeProgramReportDTOList = page.getResult();
		if(wholeProgramReportDTOList.size() == 0 || wholeProgramReportDTOList.isEmpty()) {
			return exportWholeProgramList;
		}

		for(WholeProgramReportDTO dto : wholeProgramReportDTOList) {
			WholeProgramReportVO vo = new WholeProgramReportVO();
			vo.setProgramJsonId(dto.getProgramJsonId().toString());
			vo.setPublishWay(dto.getPublishWay() == null ? "" : "定期发布");
			vo.setReceiveTime(dto.getReceiveTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getReceiveTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			vo.setDoneTime(dto.getDoneTime() == null ? "" : DateUtils.longTimeStampToStringDate(dto.getDoneTime(), DateFormatConstant.LONG_DATE_FORMAT_STR));
			vo.setDeviceNum(dto.getDeviceNum().toString());
			vo.setDeviceSuccessNum(dto.getDeviceSuccessNum().toString());
			vo.setDeviceFailNum(dto.getDeviceFailNum().toString());
			exportWholeProgramList.add(vo);
		}
		return exportWholeProgramList;
	}

	/**
	 * 获取校验未校验节目json
	 *
	 * @return List<AuthProgramJsonDTO>
	 */
	@Override
	public List<AuthProgramJsonDTO> listAuthNoPassProgramJson() {
		return programJsonMapper.listProgramJsonByJsonAuth(BusinessConstant.PROGRAMJSON_AUTH_STATE_NO_VALIDATE);
	}

	/**
	 * 通过xc版本更新节目校验状态
	 *
	 * @param jsonAuth  校验状态
	 * @param xcVersion xc版本
	 */
	@Override
	public void updateProgramJsonAuthByXcVersion(Integer jsonAuth, String xcVersion) {
		programJsonMapper.updateProgramJsonAuthByXcVersion(jsonAuth, xcVersion);
	}

}
